#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <stdatomic.h>

#define MAIN_END 1000000000
#define THREAD_END 1000000
#define MAIN_PRIORITY 10
#define THREAD_PRIORITY 20

atomic_int thread_progress = 0;
atomic_int main_finished = 0;

void *thread_runner(void *arg) {
    int thread_counter = 0;
    while (thread_counter < THREAD_END) {
        thread_counter++;
    }
    atomic_store(&thread_progress, THREAD_END);
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_attr_t attr;

    /* Main thread sched strategy */
    struct sched_param main_param = {.sched_priority = MAIN_PRIORITY};
    if (pthread_setschedparam(pthread_self(), SCHED_RR, &main_param) != 0) {
        perror("pthread_setschedparam: main");
        return -1;
    }

    /* Sub thread sched strategy */
    pthread_attr_init(&attr);
    pthread_attr_setschedpolicy(&attr, SCHED_RR);
    struct sched_param thread_param = {.sched_priority = THREAD_PRIORITY};
    pthread_attr_setschedparam(&attr, &thread_param);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    if (pthread_create(&tid, &attr, thread_runner, NULL) != 0) {
        perror("pthread_create");
        return -1;
    }

    printf("Before main thread start to run, thread progress: %d/%d\n", 
        atomic_load(&thread_progress), THREAD_END);

    /* Main thread running, expected running continously until main_counter reaches MAIN_END */
    /* During this period, scheduler run main thread since its priority is higher than the sub thread and it does not yield cpu or wating on io event either */
    volatile int main_counter = 0;
    while (main_counter < MAIN_END) {
        main_counter++;
    }
    atomic_store(&main_finished, 1);
    printf("After main thread finish, thread progress: %d/%d\n", 
        atomic_load(&thread_progress), THREAD_END);

    pthread_join(tid, NULL);
    printf("After main thread join, thread progress: %d/%d\n", 
           atomic_load(&thread_progress), THREAD_END);
    return 0;
}